package cn.wolfcode.wolf2w.redis.service.impl;

import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.redis.service.IStratrgyStatisVORedisService;
import cn.wolfcode.wolf2w.redis.util.RedisKeys;
import cn.wolfcode.wolf2w.redis.vo.StrategyStatisVO;
import cn.wolfcode.wolf2w.service.IStrategyCommentService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.util.DateUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class StrategyStatisVOServiceImpl implements IStratrgyStatisVORedisService{

    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private IStrategyCommentService commentService;

    @Override
    public void viewnumIncrease(String sid, int num) {
        //获取缓存库中的拼接key的 vo对象
        StrategyStatisVO vo = this.getStrategyStatisVO(sid);
        //统一加上阅读量
        vo.setViewnum(vo.getViewnum() + num);
        //更新vo对象
        this.setStrategyStatisVO(vo);
    }

    @Override
    public StrategyStatisVO getStrategyStatisVO(String sid) {

        //拼接vo对象key
        //strategy_statis_vo:sid
        String key = RedisKeys.STRATEGY_STATIS_VO.join(sid);
        StrategyStatisVO vo = null;
        //判断key是否存在
        if (!template.hasKey(key)){
            //如果不存在,需要初始化vo对象进入redis中
            vo = new StrategyStatisVO();
            //从数据库中查询攻略的5个统计数据
            Strategy strategy = strategyService.get(sid);
            //将统计数据设置到vo对象中
            BeanUtils.copyProperties(strategy,vo);
            vo.setStratrgyId(strategy.getId());
            //缓存到redis缓存中
            this.setStrategyStatisVO(vo);
        }else {
            //如果存在,或已经初始化,通过key获取vo的对象,viewum +1
            String voStr = template.opsForValue().get(key);
            //将json格式的voStr转换成vo对象
            vo = JSON.parseObject(voStr,StrategyStatisVO.class);
        }
        return vo;
    }

    @Override
    public void setStrategyStatisVO(StrategyStatisVO statisVO) {
        //将vo对象缓存到redis中
        String key = RedisKeys.STRATEGY_STATIS_VO.join(statisVO.getStratrgyId());
        template.opsForValue().set(key,JSON.toJSONString(statisVO));
    }

    @Override
    public void replynumIncrease(String sid,int num) {
        //获取攻略sid,拼接vo的key
        //是否存在key,不存在则初始化,存在则直接获取vo对象,replynum+1
        StrategyStatisVO vo = this.getStrategyStatisVO(sid);
        vo.setReplynum(vo.getReplynum() + num);
        this.setStrategyStatisVO(vo);
    }

    @Override
    public boolean strategyFavor(String sid,String uid) {
        //获取用户uid,通过uid拼接用户收藏的攻略id集合的keyList
        String keyList = RedisKeys.USER_STRATEGY_FAVOR.join(uid);
        //创建keyList对应的sid集合
        //如果不存在,创建keyList 和sidList缓存如redis中
        List<String> sidList = new ArrayList<>();;
        //判断key是否存在
        if (template.hasKey(keyList)){
            //如果存在直接获取sidList
            String sidsStr = template.opsForValue().get(keyList);
            //将JSON格式的sids集合转换成sidList对象
            sidList = JSON.parseArray(sidsStr,String.class);
        }
        StrategyStatisVO statisVO = this.getStrategyStatisVO(sid);
        //判断当前传入的sid是否在sidList中
        if (!sidList.contains(sid)){
            //如果不存在,当前为请求收藏操作,获取vo对象,收藏数+1,将sid存入到sidList中
            statisVO.setFavornum(statisVO.getFavornum() + 1);
            sidList.add(sid);
        }else {
            //如果存在,当前为取消收藏,获取vo对象,收藏数-1,将sid从sidList中移除
            statisVO.setFavornum(statisVO.getFavornum() - 1);
            sidList.remove(sid);
        }
        //更新缓存中的keyList,更新vo对象
        template.opsForValue().set(keyList,JSON.toJSONString(sidList));
        this.setStrategyStatisVO(statisVO);
        //System.err.println(uid);
        return sidList.contains(sid);
    }

    @Override
    public List<String> getSids(String userId) {

        //拼接用户id的key
        String key = RedisKeys.USER_STRATEGY_FAVOR.join(userId);
        //不存在直接初始化
        List<String> sidList = new ArrayList<>();
        //判断sid的集合是否存在,
        if (template.hasKey(key)){
            //如果存在直接获取其中的sids集合
            String sidStr = template.opsForValue().get(key);
            sidList = JSON.parseArray(sidStr,String.class);
        }
        return sidList;
    }

    @Override
    public boolean strategyThumbup(String sid, String uid) {
        //通过sid,和uid拼接记号key
        String key = RedisKeys.STRATEGY_THUMBUP.join(sid,uid);
        //获取vo对象
        StrategyStatisVO vo = this.getStrategyStatisVO(sid);
        //判断是否存在key
        if (!template.hasKey(key)){
            //如果不存在说明今天没点赞,获取vo对象,点赞数+1
            vo.setThumbsupnum(vo.getThumbsupnum() +1);
            //更新vo对象
            this.setStrategyStatisVO(vo);
            //将key缓存到redis中.设置有效时间,今天之内
            //获取当前时间
            Date nowTime = new Date();
            //获取当天最后时间
            Date endTime = DateUtil.getEndDate(nowTime);
            //有效时间
            Long time = DateUtil.getDateBetween(nowTime,endTime);
            template.opsForValue().set(key,"3",time,TimeUnit.SECONDS);
            return true;
        }
        //如果存在说明点赞过,不作处理

        return false;
    }

    @Override
    public boolean isExistsStrategyVO(String strategyId) {
        //拼接key
        String key = RedisKeys.STRATEGY_STATIS_VO.join(strategyId);

        return template.hasKey(key);
    }

    @Override
    public List<StrategyStatisVO> queryStrategyVO() {
        //拼接keys : *
        String pattern = RedisKeys.STRATEGY_STATIS_VO.join("*");
        //查询到vo对象的所有key值
        Set<String> vokeys = template.keys(pattern);
        //遍历所有key值
        List<StrategyStatisVO> voList = new ArrayList<>();
        if (vokeys != null && vokeys.size()> 0){
            for (String key : vokeys){
                //查询到每个key对应的vo对象,存入到list中
                String  voStr = template.opsForValue().get(key);
                voList.add(JSON.parseObject(voStr,StrategyStatisVO.class));
            }
        }
        return voList;
    }

}
